#pragma once

/**
 * @file perf_utils.h
 * @brief 性能测量工具
 * @details 提供高精度时间测量和性能分析的工具函数和宏
 */

namespace Common {
  /**
   * @namespace Common
   * @brief 包含常用工具类和函数的命名空间
   */
  /**
   * @brief 读取TSC寄存器并返回代表CPU时钟周期的值
   * @details 使用RDTSC指令获取处理器时间戳计数器的值，用于高精度时间测量
   * @return 返回64位无符号整数表示的CPU时钟周期数
   */
  inline auto rdtsc() noexcept {
    unsigned int lo, hi;
    __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
    return ((uint64_t) hi << 32) | lo;
  }
}

/**
 * @brief 开始延迟测量
 * @details 使用rdtsc()函数开始测量，并在当前作用域创建一个名为TAG的变量
 * @param TAG 测量标识符，用于标识不同的测量点
 */
#define START_MEASURE(TAG) const auto TAG = Common::rdtsc()

/**
 * @brief 结束延迟测量
 * @details 使用rdtsc()函数结束测量，并计算从开始到结束的时钟周期数
 * @param TAG 测量标识符，必须与START_MEASURE中的TAG相同
 * @param LOGGER 日志对象，用于记录测量结果
 */
#define END_MEASURE(TAG, LOGGER)                                                              \
      do {                                                                                    \
        const auto end = Common::rdtsc();                                                     \
        LOGGER.log("% RDTSC "#TAG" %\n", Common::getCurrentTimeStr(&time_str_), (end - TAG)); \
      } while(false)

/**
 * @brief 记录当前时间戳
 * @details 获取并记录宏被调用时的纳秒级时间戳
 * @param TAG 时间戳标识符，用于标识不同的时间点
 * @param LOGGER 日志对象，用于记录时间戳
 */
#define TTT_MEASURE(TAG, LOGGER)                                                              \
      do {                                                                                    \
        const auto TAG = Common::getCurrentNanos();                                           \
        LOGGER.log("% TTT "#TAG" %\n", Common::getCurrentTimeStr(&time_str_), TAG);           \
      } while(false)
